package com.wxg.algorithm.chapter02.util;

import com.wxg.algorithm.common.ISort;

import java.util.Random;

public class SortTestHelper {

    /**
     * 2018年08月01日
     * // 生成有n个元素的随机数组, 每个元素的随机范围为[rangL, rangR]
     *
     * `arr[i] = random.nextInt() % (rangR - rangL + 1) + rangL;` 这是在 C++ 中的写法
     *
     * `arr[i] = random.nextInt(rangR - rangL + 1) + rangL;` Java中应该这样写
     *
     * @param n
     * @param rangL
     * @param rangR
     * @return
     */
    public static Integer[] generateRandomArray(int n, int rangL, int rangR){

        assert rangL <= rangR;

//        if(rangR > rangL){
////            throw new Exception(String.format("rangL(%d)必须小于等于rangR(%d)", rangL, rangR));
////            throw new Exception(String.format("rangL(%d)必须小于等于rangR(%d)", rangL, rangR));
//        }
        Integer[] arr = new Integer[n];
        Random random = new Random();
        for(int i=0; i<n; i++){
            arr[i] = random.nextInt(rangR - rangL + 1) + rangL;
        }
        return arr;
    }

    public static Integer[] generateNearlyOrderedArray(int n, int swapTimes){
        Integer[] arr = new Integer[n];
        for(int i=0; i<n; i++){
            arr[i] = i;
        }
        Random rand = new Random();
        for(int i=0; i<swapTimes; i++){
            int posx = rand.nextInt(n);
            int posy = rand.nextInt(n);
            Integer temp = arr[posx];
            arr[posx] = arr[posy];
            arr[posy] = temp;
        }
        return arr;
    }

    public static void printArray(Object[] arr){
        for (int i=0; i<arr.length; i++){
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    /**
     * 这里还不能写 `Comparable&lt;?&gt;[] arr`, 泛型的知识得好好复习下啦。
     *
     * @param arr
     * @return
     */
    public static boolean isSorted(Comparable[] arr){
        for(int i=0; i<arr.length-1; i++){
            if( arr[i].compareTo(arr[i+1]) > 0){
                return false;
            }
        }
        return true;
    }

    public static void testSort(ISort sortInstance, Comparable[] arr){
        long begin = System.currentTimeMillis();
        sortInstance.sort(arr);
        long end   = System.currentTimeMillis();

//        assert isSorted(arr);
        if(!isSorted(arr)){
            throw new Error("isSorted : false");
//            throw new RuntimeException("isSorted : false");
        }

        System.out.println(String.format("%s : %s ms", sortInstance.getClass().getSimpleName(), (end - begin)));
    }

    public static Integer[] copyIntArray(Integer[] arr){
        Integer[] destArr = new Integer[arr.length];
        System.arraycopy(arr, 0, destArr, 0, arr.length);
        return destArr;
    }
}
